﻿/*
 *	Copyright (c) 2009 Queensland University of Technology. All rights reserved.
 *	The QUT Bioinformatics Collection is open source software released under the 
 *	Microsoft Public License (Ms-PL): http://www.microsoft.com/opensource/licenses.mspx.
 */
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Windows;
#if ! SILVERLIGHT
	using System.Web;
#else
using System.Windows.Browser;
#endif
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using QUT.Bio.Util;

namespace QUT.Bio.SilverMap {
	/// <summary>
	/// Snapshot is intended to allow easy sharing and embedding of a specific collection in a web page.
	/// </summary>

	public partial class Snapshot : UserControl {
		// TODO: Make Snapshot properly application independent.
	
		private PopupWindow window = new PopupWindow();
		private ViewModel model;
		private View view;

		public Snapshot () {
			InitializeComponent();
		}

		public void Init (
			ViewModel model,
			View view
		) {
			this.model = model;
			this.view = view;

			window.Title = "HTML snapshot";
			window.ClientArea.Centre = this;
			window.WindowChanged += WindowChanged;

			refreshButton.Click += delegate( object sender, RoutedEventArgs args ) {
				Refresh();
			};

			htmlCopyButton.Click += delegate( object sender, RoutedEventArgs args ) {
#if SILVERLIGHT
				ClipboardDemo.Clipboard.SetClipboardText( htmlTextBlock.Text );
#endif
			};

			urlCopyButton.Click += delegate( object sender, RoutedEventArgs args ) {
#if SILVERLIGHT
				ClipboardDemo.Clipboard.SetClipboardText( urlTextBlock.Text );
#endif
			};
		}

		public PopupWindow Window {
			get {
				return window;
			}
		}

		private void Write (
			ref bool dejaVu,
			TextWriter htmlWriter,
			TextWriter urlWriter,
			string parameterName,
			string parameterValueFormat,
			params object[] parameterValueComponents
		) {
			htmlWriter.Write( "{0}{1}={2}",
				dejaVu ? "," : "",
				HttpUtility.HtmlEncode( parameterName ),
				HttpUtility.HtmlEncode( String.Format( parameterValueFormat, parameterValueComponents ) )
			);

			urlWriter.Write( "{0}{1}={2}",
				dejaVu ? "&" : "",
				HttpUtility.UrlEncode( parameterName ),
				HttpUtility.UrlEncode( String.Format( parameterValueFormat, parameterValueComponents ) )
			);

			dejaVu = true;
		}

		private void Refresh () {
			bool dejaVu = false;
			StringWriter htmlWriter = new StringWriter();
			StringWriter urlWriter = new StringWriter();

			Write( ref dejaVu, htmlWriter, urlWriter, "AutoLoad", "True" );
			Write( ref dejaVu, htmlWriter, urlWriter, "DistanceType", "{0}", model.DistanceType );
			Write( ref dejaVu, htmlWriter, urlWriter, "Cutoff", "{0}", model.Cutoff );

			if ( model.ReferenceSequence != null ) {
				Write( ref dejaVu, htmlWriter, urlWriter, "Reference", "{0}", model.ReferenceSequence.Id );
			}

			// TODO: Fix this in some application-neutral manner.
			/*
			string [] subjects = model.;

			if ( subjects != null && subjects.Length > 0 ) {
				Write( ref dejaVu, htmlWriter, urlWriter, "Subjects", "{0}", string.Join( ";", subjects ) );
			}

			Write( ref dejaVu, htmlWriter, urlWriter, "MapWebService", "{0}", model.DataLayer == null ? "null" : model.DataLayer.WebServiceAddress );

			Write( ref dejaVu, htmlWriter, urlWriter, "TagWebService", "{0}", TagModule.Tags.WebServiceAddress );
			
			Write( ref dejaVu, htmlWriter, urlWriter, "UseTags", "{0}", model.TagsEnabled );
			 */

			string [] selected = (from seq in model.SelectedSequences select seq.Id).ToArray();

			if ( selected != null && selected.Length > 0 ) {
				StringWriter subjectWriter = new StringWriter();

				for ( int i = 0; i < selected.Length; i++ ) {
					subjectWriter.Write( "{0}{1}", ( i > 0 ? ";" : "" ), selected[i] );
				}

				Write( ref dejaVu, htmlWriter, urlWriter, "Selected", "{0}", subjectWriter );
			}

			htmlTextBlock.Text = string.Format( htmlTemplate, htmlWriter );

#if SILVERLIGHT
			urlTextBlock.Text = string.Format( "{0}?{1}", HtmlPage.Document.DocumentUri, urlWriter );
#else
			urlTextBlock.Text = urlWriter.ToString();
#endif
		}

		private void WindowChanged ( PopupWindow window, WindowChangeEventType windowChange ) {
			if ( windowChange == WindowChangeEventType.WindowShown ) {
				Refresh();
			}
		}

		private static readonly string htmlTemplate = @"
<div id='silverlightControlHost' style='width: 100%; height=100%'>
	<script type='text/javascript'>
		function onSilverlightError(sender, args) {{

			var appSource = '';
			if (sender != null && sender != 0) {{
				appSource = sender.getHost().Source;
			}}
			var errorType = args.ErrorType;
			var iErrorCode = args.ErrorCode;

			var errMsg = 'Unhandled Error in Silverlight 2 Application ' + appSource + '\n';

			errMsg += 'Code: ' + iErrorCode + '    \n';
			errMsg += 'Category: ' + errorType + '       \n';
			errMsg += 'Message: ' + args.ErrorMessage + '     \n';

			if (errorType == 'ParserError') {{
				errMsg += 'File: ' + args.xamlFile + '     \n';
				errMsg += 'Line: ' + args.lineNumber + '     \n';
				errMsg += 'Position: ' + args.charPosition + '     \n';
			}}
			else if (errorType == 'RuntimeError') {{
				if (args.lineNumber != 0) {{
					errMsg += 'Line: ' + args.lineNumber + '     \n';
					errMsg += 'Position: ' + args.charPosition + '     \n';
				}}
				errMsg += 'MethodName: ' + args.methodName + '     \n';
			}}

			throw new Error(errMsg);
		}}
	</script>
	<object data='data:application/x-silverlight-2,' type='application/x-silverlight-2' width='100%' height='100%'>
		<param name='source' value='ClientBin/SilverMap.xap'/>
		<param name='onerror' value='onSilverlightError' />
		<param name='background' value='white' />
		<param name='minRuntimeVersion' value='2.0.31005.0' />
		<param name='autoUpgrade' value='true' />
		<a href='http://go.microsoft.com/fwlink/?LinkID=124807' style='text-decoration: none;'>
 			<img src='http://go.microsoft.com/fwlink/?LinkId=108181' alt='Get Microsoft Silverlight' style='border-style: none'/>
		</a>
		<param name='initParams' value='{0}'/>
	</object>
	<iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe>
</div>
";
	}
}
